home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
tde.zip
/
TDE.DOC
< prev
next >
Wrap
Text File
|
1992-07-14
|
22KB
|
485 lines
FILENAME: TDE.DOC
*****************
Class TDataEntry v1.0 - 07/14/92
--------------------------------
----------------------------------------------------------------------------
Author: Jeff Penrose * JDP Custom Software * (818) 344-7303 * CIS 71043,3727
----------------------------------------------------------------------------
A data entry class for Borland's Turbo Vision, derived from TInputLine.
TDataEntry's Features
=====================
* non-scrollable input lines
* data entry masks consisting of writable/non-writable positions
* field validation/required checks
* field auto-exit
* field location by name and/or number
* user restoral of original field data (CTRL-R)
* queries: field changed/field valid either global or field-specific
* option to treat ENTER like TAB, up/down arrow inter-field movement,
validation immediately or at a later time (such as when saving)
* special derivatives of TInputLine/TCluster which inherit some of the
functionality of TDataEntry so field behavior is consistent
TDataEntry's Philosophy
=======================
I needed a class which allowed me to keep tabs on what the user was entering,
control the presentation of data, and be able to quickly locate a field
without having to keep a bunch of field pointers hanging around.
I wanted strong validation capabilites, including checking for missing data.
I wanted to have certain types of data fields (such as states, zip codes,
phone numbers) to automatically exit when the user entered the last character,
without having to hit RETURN.
I wanted to be able to use the RETURN key for inter-field movement, as well
as the up/down arrow keys.
At the same time, I realized that MOST of the fields which I created would
be displayed in their entirety. If a customer name field is used, I didn't
want it to be scrollable, since the user probably would want to see the
whole thing on screen anyway.
Finally, I wanted to be able to turn on/off the above-mentioned features; I
wanted flexibility.
Copyright Notice
================
As this material is ultimately derived from Borland source files, any of
their copyrights which MAY apply DO apply.
From the author's standpoint, you may use this material freely and,
hopefully, post any comments/corrections/enhancements to me at the above-
noted addresses. I do ask that you not distribute this material except as
originally received, including all source/documentation files in their
original form.
If you DO modify or enhance any of this code, please send any such changes
to me for incorporation into a future version. Any such enhancements will
be DONATED, without expectation of compensation or incorporation into
future versions. Again, if you distribute this code, please do so in its
original, unmodified form including all source files and documentation.
Source files included
=====================
TDE .DOC: This documentation.
TDE .MAN: How to use TDataEntry in your dialog objects
TDE .H : header file containing class declarations for classes
TDEFLAGS.H : " " " flags and command definitions
TDE .CPP: Class TDataEntry
TDEDATE .CPP: Class TDEDate
TDEPHONE.CPP: Classes TDEPhone, TDEZipCode, TDEState
TDENUMS .CPP: Class TDEInteger
TDECLUST.CPP: Non-TDataEntry classes TDEButton, TDERadioButtons, TDECheckBoxes
TDEINPLI.CPP: Non-TDataEntry class TDEInputLine
TDELIB .PRJ: Project for building library TDELIB.LIB
TDEDEMO .CPP: Demo program
TDEDEMO .PRJ: Project for building TDEDEMO.EXE
What's Missing?
===============
I haven't yet made TDataEntry streamable, nor has data formatting been
incorporated. I'm sure other stuff is missing -- please let me know.
The source provided is lacking most of the development comments, etc.
During development, all changes/corrections were meticulously documented and
this added up to voluminous comments which would only clutter the source and
increase download time. Therefore, you must be especially careful when
tinkering with the code. If you have any questions, please post a message
to me.
Class TDataEntry Summary of Class Members: TDE.H, TDE.CPP
=========================================================
public:
**
MASK_CHAR:
The default mask character, '~'. Within a mask, this character indicates
that data may be entered in that position. Currently their is no
method for including MASK_CHAR literally within a mask.
**
uchar localMode:
The mode characteristics specific to a particular instance, which is a
combination of OR'd tdlXXXXXXX flags defined in TDEFLAGS.H.
**
ushort dataFormat:
The dataFormat flags for a particular instance, NOT YET IMPLEMENTED.
**
static uchar globalID:
The global field number counter. This should be initialized to zero
at the beginning of creation of each dialog containing TDataEntry
objects. TDataEntry objects will then be numbered consecutively from
1 - 255 which will allow them to be located via a call to
TDataEntry::locateID.
**
static ushort globalMode
The global mode characteristics which affect ALL instances of TDataEntry
objects, which is a combination of OR'd tdgXXXXXX flags defined in
TDEFLAGS.H.
**
static char *msgDataRequired:
The default message to be displayed when a required field is not filled
in. This is used if the field uses the default validData() function, or
does not define its own message in its validData() function.
Default definition:
char *TDataEntry::msgDataRequired = "\003Required data is missing!";
**
static char *msgDataInvalid
Same as msgDataRequired, except for the case when data is invalid.
Default definition:
char *TDataEntry::msgDataInvalid = "\003Invalid data!";
**
static char secureChar:
The default secure character. If the fields localMode includes the
tdlSecure mask, then all input is displayed using this character. To
be used for password fields, etc. Default definition:
char TDataEntry::secureChar = '#';
**
CONSTRUCTOR 1:
-------------
TDataEntry(int col, int row, char *format, const char *fName = NULL ):
Creates a TDataEntry object at 'col', 'row' within its owner, using a
format mask defined 'format'. Its length will be the length of 'format',
and it will be assigned a field name of 'fName' if non-NULL. The actual
length of its data member (inherited from TInputLine) will be the length
of 'format' minus the total number of non-MASK characters in 'format'.
**
CONSTRUCTOR 2:
-------------
TDataEntry(int col, int row, int len, const char *fName = NULL ):
Creates a TDataEntry object at 'col', 'row' within its owner, of length
'len'. This constructor is used when ALL positions are writable and is
equivalent to calling CONSTRUCTOR 1 with a format = 'len' MASK char's.
**
DESTRUCTOR:
----------
~TDataEntry():
Cleans up the heap. (Some data is inherited from TInputLine, which is
why the destructor does not destroy these members.)
**
void selectAll( Boolean enable ):
A TDataEntry-specific version of TInputLine's selectAll(). Since
selectAll() is NOT virtual in TInputLine, you have to be careful when
other classes call selectAll() (such as THistory). In these cases,
TInputLine's selectAll() will be called with undesirable results. A
solution for THistory is documented in TDE.MAN.
**
virtual ushort dataSize():
virtual void getData( void *rec ):
virtual void setData( void *rec ):
virtual Boolean valid(ushort):
These are all fairly standard deviations/derivations of standard TV
functions. Some must be overridden in derived classes.
**
virtual void draw():
virtual void handleEvent(TEvent& event):
virtual void setState( ushort aState, Boolean enable ):
These are TDataEntry-specific versions which probably should not be
tampered with.
**
virtual Boolean validData( const char *InvalidMsg, char const *RequiredMsg ):
The default validData() calls the validKey() function to double check
valid input. Override in derived classes for more detailed checking
of validity.
**
virtual Boolean validKey(uchar *key ) { return (Boolean)isprint(*key); }:
The default validKey() accepts any printable character. Override in
derived classes for different behavior (eg, numbers only).
**
static inline TDataEntry *locateID( TView *fieldOwner, uchar fieldNumber,
Boolean select = False ):
This function sends a broadcast message with command 'cmTDGotoNumber' to
'fieldOwner', which a TDataEntry object with localID member = fieldNumber
will respond to. If 'select' is True, the field will be selected,
otherwise it won't. Returns a pointer to the field, NULL if not found.
**
static inline TDataEntry *locateName( TView *fieldOwner, const char *fName,
Boolean select = False ):
This function sends a broadcast message with command 'cmTDGotoName' to
'fieldOwner', which a TDataEntry object with fieldName member = fName
will respond to. If 'select' is True, the field will be selected,
otherwise it won't. Returns a pointer to the field, NULL if not found.
**
static inline void resetData( TView *fieldOwner, TDataEntry *target = NULL):
This function sends a broadcast message with command 'cmTDResetData' to
'fieldOwner'. If 'target' != NULL, then only 'target' (if found) will reset
its data. Otherwise, ALL of fieldOwner's TDataEntry objects will reset
their data. Resetting data copies the contents of the field's 'data'
member into its 'origData' member. After a call to resetData, calls to
TDataEntry::queryChanged() will return False until data is once again
modified. This is useful when you save the contents of a dialog to
disk but want the dialog to remain displayed. Resetting the data after
the save will prevent you from re-saving the data if it hasn't been
further modified.
**
static inline TDataEntry *queryChanged( TView *fieldOwner, TDataEntry *target = NULL):
This function sends a broadcast message with command 'cmTDQueryChanged' to
'fieldOwner'. If 'target' != NULL, then only 'target' MIGHT respond,
otherwise ALL of fieldOwner's TDataEntry objects will receive the message.
This function returns a pointer to the FIRST field which responds in the
affirmative, NULL if no data has been changed or, if 'target' is specified,
if 'target' isn't found.
**
static inline TDataEntry *queryValid( TView *fieldOwner, TDataEntry *target = NULL):
This functions sends a broadcast message with command 'cmTDQueryValid' to
'fieldOwner'. If 'target' != NULL, then only 'target' MIGHT respond,
otherwise ALL of fieldOwner's TDataEntry objects will receive the message.
The function returns a pointer to the FIRST field which contains invalid
data, NULL if all data is valid or, if 'target' is specified, if 'target'
isn't found.
protected:
**
char *mask:
This member contains a copy of the 'format' argument passed by
CONSTRUCTOR 1, or one created by CONSTRUCTOR 2.
**
char *outView:
This member contains a picture of the field as viewed on the screen.
**
char *origData:
This member contains a copy of 'data' as set by setData() and is used
when querying if field contents have changed.
**
int tdCurPos:
int tdLastPos:
int tdSelStart:
int tdSelEnd:
These members are used internally to keep track of current positions
within outView and mask. They should NOT be tampered with.
**
ushort localID:
This contains the field number for the object. If you initialize
TDataEntry::globalID to 0 at the beginning of creation of a dialog box,
then all TDataEntry objects within the box will be assigned localID's
within the range 1 - 255. Once TDataEntry::globalID hits 255, all
objects created will then be numbered with 255. You can use localID to
locate a field by number.
**
char *fieldName:
If 'fName' is passed to the constructor, then fieldName will contain
'fName'. You can then locate the field by name.
private:
**
int mousePos( TEvent& event ):
void deleteSelect():
void near setViewPos(ushort):
void near formatView():
None of these should be messed with.
INHERITED FROM TInputLine:
-------------------------
public:
**
char *data:
Contains the raw field data. TDataEntry's CONSTRUCTOR 1 deletes this
and allocates a new one of a length less the number of non-MASK char's.
**
int maxLen:
Contains the maximum data length. TDataEntry's constructors may alter
this value.
**
int curPos:
int firstPos:
int selStart:
int selEnd:
These members are used pretty much as they are in TInputLine. They
keep track of positions within the 'data' member, as compared to their
tdXXXX counterparts, which track position with the mask and outView.
TDataEntry flags and commands: TDEFLAGS.H
=========================================
Global control flags
--------------------
These flags are used to set TDataEntry's static globalMode data member. ALL
TDataEntry objects are affected by these flags. You set globalMode by
logically OR'ing the flags. By default, TDataEntry::globalMode is defined
as follows:
ushort TDataEntry::globalMode = (tdgBeepEnable | tdgSelectOnFocus);
* tdgEnterIsTab
This flag makes the ENTER/RETURN key behave like the TAB key. By default,
ENTER pushes the default button, usually resulting in exit from the
dialog. Using this flag allows inter-field movement via the ENTER key.
* tdgBeepEnable
This flag enables sound for validation error, etc. (on by default)
* tdgUpDownEnable
This flag makes the UP/DOWN arrow keys behave like TAB/SHIFT-TAB, allowing
UP/DOWN to be used for inter-field movement.
* tdgValidNow
This flag enables immediate validation when exiting a field via TAB,
SHIFT-TAB, ENTER (if enabled), or arrow keys (if enabled; see below).
If you don't choose immediate validation, you can call
TDataEntry::queryValid() before exiting the dialog. Currently, field
validation is NOT perform when a field is exited via mouse movement.
Therefore, TDataEntry::queryValid() should ALWAYS be called prior to
saving data or whatever it is you want to do with the data.
* tdgValidUpDown
This flag enables immediate validation when UP/DOWN arrow movement causes
exit from a field. It only works if the tdgValidNow and tdgUpDownEnable
are enabled.
* tdgSelectOnFocus
If enabled (the default), then a field's contents are selected when
the field recieves focus (like TInputLine). I've run into users who get
extremely angry when the first keystroke deletes the field contents so
its nice to let the user be able to toggle this.
* tdgReserved_2
* tdgReserved_3
* tdgReserved_4
* tdgReserved_5
Unused.
Local control flags
-------------------
These flags are used to set each field's localMode data member, allowing each
field to behave differently depending on its unique requirements. By
default, each object's localMode is set as follows:
localMode = tdlRLArrows | tdlInsertEnable;
* tdlAutoExit
If enabled, the field exits automatically when a valid character is
typed in the last field position. Handy for dates, phone numbers, etc.
* tdlRightToLeft
Unused. Originally intended for a TDataEntry object which employs
right-to-left calculator-style field movement. That project's on hold
right now. I think TDataEntry is big enough and that a right-to-left
implementation will need to be a completely separate object.
* tdlRLArrows
Unused. Originally intended to be used in a right-to-left object as
described above.
* tdlInsertEnable
Enables the insert toggle (on by default).
* tdlRequired
This flag informs the field's validData() that the data is required;
validation will fail if this flag is set and the field is left blank.
* tdlSecure
If set, then all valid characters will be displayed using the
static TDataEntry::secureChar (default = '#'). Useful for passwords or
other 'secret' data.
Format control flags - sets dataFormat - local to each TDE object
-----------------------------------------------------------------
Data formatting is not yet implemented, so these flags are currently
unused but are documented with their intended purpose.
* tdfUpper
If set, data is converted to uppercase.
* tdfLower
If set, data is converted to lowercase.
* tdfRightJust
If set, data is right-justified, padded on left with spaces up to maxLen.
* tdfLeftJust
If set, data is left-justified, padded on right with spaces up to maxLen.
* tdfCenter
If set, data is centered, padded on right/left with spaces up to maxLen.
TDataEntry commands
-------------------
These commands are used by the static query functions. They may be used
directly in the message() function if you study their use in the query
functions. If they conflict with any command constants which you've defined,
you'll need to change them. The following documents which function uses the
command; refer to the function description above for a description of the
function's behavior.
* cmTDQueryValid 41456u
Used by TDataEntry::queryValid().
* cmTDQueryValidQuiet 41457u
Unused. Intended to behave like cmTDQueryValid except to do so quietly.
* cmTDQueryChanged 41458u
Used by TDataEntry::queryChanged().
* cmTDGotoNumber 48459u
Used by TDataEntry::locateID().
* cmTDGotoName 48560u
Used by TDataEntry::locateName().
* cmTDResetData 48561u
Used by TDataEntry::resetData(). See description of this function above.
Sample derived classes included
================================
class TDEAlpha - alpha strings only ( TDE.H )
----------------------------------------------
This class allows only alphabetic data to be entered. Data type is string.
class TDEAlphaNum - alphanumeric strings only ( TDE.H )
--------------------------------------------------------
This class allows only alphanumeric data to be entered. Data type is string.
class TDENumeric - numeric strings only ( TDE.CPP )
----------------------------------------------------
This class allows only numeric data to be entered. If its SpaceAllowed data
member is True, data may contain numbers AND spaces, otherwise spaces will
not be allowed. Data type is string.
class TDEInteger - signed integer values ( TDENUMS.CPP )
--------------------------------------------------------
This class allows only signed integer data to be entered (it currently
doesn't accept the minus sign, however...that was overlooked. So, in effect,
it only accepts unsigned integers but stores them as signed int). Data type
is integer.
class TDEDate - date strings only (TDEDATE.CPP)
-----------------------------------------------
This class allows dates of the form xx/xx/xx or xx/xx/xxxx to be entered.
Data type is unsigned long. Static members control default century and format:
TDEDate::defCentury = 19 by default. defCentury is used in fields of the
form xx/xx/xx, where century is not input but is assumed.
TDEDate::defFormat = dateMDY. This field controls the order in which
month, day, and year are entered. See the #defines in the source.
class TDEPhone - phone number strings only (TDEPHONE.CPP)
---------------------------------------------------------
Accepts phone numbers in the form (xxx) xxx-xxx. Data type is string.
class TDEZipCode - zip code strings only (TDEPHONE.CPP)
-------------------------------------------------------
Accepts zip codes in the form xxxxx or xxxxx-xxxx. Data type is string.
class TDEState - state abbreviation strings only (TDEPHONE.CPP)
---------------------------------------------------------------
Accepts two digit state codes and capitalizes them. Data type is string.
class TDEButton ( TDECLUST.CPP )
--------------------------------
This is a non-TDataEntry TButton derivative which is designed to handle
arrow-key movement consistent with the behavior of TDataEntry objects.
class TDEInputLine ( TDEINPLI.CPP )
------------------------------------
This is a non-TDataENtry TInputLine derivative which is designed to handle
enter/arrow-key movement consistent with the behavior of TDataEntry objects.
In addition, it responds to CTRL-R and the TDataEntry query functions.
class TDERadioButtons ( TDECLUST.CPP )
---------------------------------------
This is a non-TDataEntry TRadioButtons derivative which is designed to
handle enter key movement consistent with the behavior of TDataEntry
objects. In addition, it responds to the TDataEntry query functions. (It's
easy for the user to 'restore' button data, so CTRL-R logic is omitted.)
Up/down arrow movement is not modified.
class TDECheckBoxes ( TDECLUST.CPP )
-------------------------------------
This is a non-TDataEntry TCheckBoxes derivative which is designed to
handle enter key movement consistent with the behavior of TDataEntry
objects. In addition, it responds to the TDataEntry query functions. (It's
easy for the user to 'restore' button data, so CTRL-R logic is omitted.)
Up/down arrow movement is not modified.
//******************** TDE.DOC ends ***************************//